#include "channel_rank_mgr.h"
#include "global_server.h"

bool coinRankSortFunc(const RankData &data1, const RankData &data2)
{
	std::map<int, long>::const_iterator d1 = data1.items.find(COIN);
	std::map<int, long>::const_iterator d2 = data2.items.find(COIN);
	if (d1 == data1.items.end())
	{
		if (d2 == data2.items.end()) return data1.record_time < data2.record_time;
		else return false;
	}
	else
	{
		if (d2 == data2.items.end()) return true;
		else
		{
			if (d2->second == d1->second) return data1.record_time < data2.record_time;
			else return d1->second > d2->second;
		}
	}
	return false;
}

bool warheadRankSortFunc(const RankData &r1, const RankData &r2)
{
	for(size_t i = 0; i < DT_NUM; ++i)
	{
		std::map<int, long>::const_iterator i1 = r1.items.find(DT[i]);
		std::map<int, long>::const_iterator i2 = r2.items.find(DT[i]);
		if(i1 == r1.items.end())
		{
			if(i2 != r2.items.end()) return false;
		}
		else
		{
			if(i2 == r2.items.end()) return true;
			if(i1->second > i2->second) return true;
			else if(i1->second < i2->second) return false;
		}
	}
	return r1.record_time < r2.record_time;
}

bool meterialRankSortFunc(const RankData &r1, const RankData &r2)
{
	for(size_t i = 0; i < CL_NUM; ++i)
	{
		std::map<int, long>::const_iterator i1 = r1.items.find(CL[i]);
		std::map<int, long>::const_iterator i2 = r2.items.find(CL[i]);
		if(i1 == r1.items.end())
		{
			if(i2 != r2.items.end()) return false;
		}
		else
		{
			if(i2 == r2.items.end()) return true;
			if(i1->second > i2->second) return true;
			else if(i1->second < i2->second) return false;
		}
	}
	return r1.record_time < r2.record_time;
}


void ChannelRankMgr::init(GlobalServer *pServer)
{
	if (pServer != NULL)
	{
		m_nRefreshTime = time(NULL);
		m_pRollLog = pServer->m_pRollLog;
		m_pDbMgr = pServer->m_pDbMgr;
		this->load();
	}
}

void ChannelRankMgr::load(const int &nRankType)
{
	QueryParam param;
	param.tableName = TBL_CHANNEL_RANK_DATA;
	DataVector vecData;
	param.userIdFiledName = "rank_type";
	for (int i = 0; i < gChannelTypeLength; ++i)
	{
		param.userid = gChannelTypeList[i];
		vecData.clear();
	    m_pDbMgr->get(param, vecData);
	    int nChannelID = 0;
	    for (int j = 0; j < vecData.size(); ++j)
	    {
	    	msgpack::unpacked unpack;   
	        msgpack::unpack(&unpack, vecData[j].data(), vecData[j].size());
	        msgpack::object  obj = unpack.get();
	        stringstream ss;
	        ss << obj;
	        m_pRollLog->normal("ChannelRankMgr::load buffer[%d:%s]", gChannelTypeList[i], ss.str().c_str());
	        Json::Reader reader;
	        Json::Value value;
	        if (reader.parse(ss.str(), value))
	        {
	        	int nType = value["rank_type"].asInt();
	        	int nChannel = value["channel_id"].asInt(); //配置ID * 1000 + index
	        	if (nChannelID <= 0) nChannelID = nChannel / gChannelIDLimit;
	        	string strBuffer = value["buffer"].asString();
	        	initRandData(nType, nChannel, strBuffer);
	        }
	    }
	    //因redis读取出来的数据没有先后顺序，需要重新排序
        if (nChannelID > 0)
        {
        	this->sort(gChannelTypeList[i], nChannelID, false);
        	nChannelID = 0;
        	//把实时榜赋值于展示榜显示
        	mapRankType2RankMapData::iterator iter = m_mapRealTimeRankData.begin();
			mapChannel2RankData::iterator it;
			for (; iter != m_mapRealTimeRankData.end(); ++iter)
			{
				if (m_mapShowTimeRankData.find(iter->first) == m_mapShowTimeRankData.end())
				{
					mapChannel2RankData mapTmp;
					m_mapShowTimeRankData[iter->first] = mapTmp;
				}
				it = iter->second.begin();
				for (; it != iter->second.end(); ++it)
				{
					if (m_mapShowTimeRankData[iter->first].find(it->first) == m_mapShowTimeRankData[iter->first].end())
					{
						vector<RankData> vecTmp(it->second);
						m_mapShowTimeRankData[iter->first][it->first] = vecTmp;
					}
				}
			}
        }
	}	
}

void ChannelRankMgr::initPlayerRandData(RankData &data) //重启时直接数据库redis拿数据，不必要再保存数据库
{
	if (data.uid > 0)
	{
		//等级，vip
		QueryParam param;
		param.tableName = TBL_PLAYER_CONTRIBUTION + base::i2s(data.uid%10);
		param.keyFieldName = "uid";
		param.key = data.uid;
		DataVector vecData;
	    m_pDbMgr->get(param, vecData);
	    if (vecData.size() > 0)
	    {
	    	msgpack::unpacked unpack;   
	        msgpack::unpack(&unpack, vecData[0].data(), vecData[0].size());
	        msgpack::object  obj = unpack.get();
	        stringstream ss;
	        ss << obj;
	        m_pRollLog->debug("ChannelRankMgr::initPlayerRandData vip level buffer[%d:%s]", data.uid, ss.str().c_str());

	        Json::Reader reader;
	        Json::Value value;
	        if (reader.parse(ss.str(), value))
	        {
	        	if (value.isMember("level")) data.level = value["level"].asInt();
	        	if (value.isMember("vip")) data.vip = value["vip"].asInt();
	        }
	    }
		//facelook,sing,nick,channel
		vecData.clear();
		param.tableName = TBL_PLAYER + base::i2s(data.uid%10);
		m_pDbMgr->get(param, vecData);
		if (vecData.size() > 0)
		{
			msgpack::unpacked unpack;   
	        msgpack::unpack(&unpack, vecData[0].data(), vecData[0].size());
	        msgpack::object  obj = unpack.get();
	        stringstream ss;
	        ss << obj;
	        m_pRollLog->debug("ChannelRankMgr::initPlayerRandData facelook, sign, nick, channel buffer[%d:%s]", data.uid, ss.str().c_str());

	        Json::Reader reader;
	        Json::Value value;
	        if (reader.parse(ss.str(), value))
	        {
	        	if (value.isMember("nick")) data.nick = value["nick"].asString();
	        	if (value.isMember("facelook")) data.facelook = value["facelook"].asString();
	        	if (value.isMember("feel")) data.sign = value["feel"].asString();
	        	if (value.isMember("channel_id")) data.channel = value["channel_id"].asString();
	        }
		}
	}
}

void ChannelRankMgr::initPlayerRandData(const string &strTool, map<int, long> &mapOut)
{
	//tid1:tnum1,tid2:tnum2,....
	if (!strTool.empty())
	{
		vector<string> vecOne;
		vector<string> vecTwo;
		common_utils::split_string(strTool, vecOne, ",");
		for (int i = 0; i < vecOne.size(); ++i)
		{
			vecTwo.clear();
			common_utils::split_string(vecOne[i], vecTwo, ":");
			if (vecTwo.size() > 1)
			{
				int nTid = base::s2i(vecTwo[0]);
				int nNum = base::s2i(vecTwo[1]);
				mapOut[nTid] = nNum;
			}
		}
	}
}

void ChannelRankMgr::initRandData(const int &nType, const int &nChannel, const string &strBuffer)
{
	int nChannelTmp = nChannel / gChannelIDLimit;
	//实时榜
	if (m_mapRealTimeRankData.find(nType) == m_mapRealTimeRankData.end())
	{
		mapChannel2RankData mapTmp;
		m_mapRealTimeRankData[nType] = mapTmp;
	}
	if (m_mapRealTimeRankData[nType].find(nChannelTmp) == m_mapRealTimeRankData[nType].end())
	{
		vector<RankData> vecTmp;
		m_mapRealTimeRankData[nType][nChannelTmp] = vecTmp;
	}
	//记录索引
	if (m_mapSaveIndex.find(nType) == m_mapSaveIndex.end())
	{
		map<int, int> mapTmp;
		m_mapSaveIndex[nType] = mapTmp;
	}
	if (m_mapSaveIndex[nType].find(nChannelTmp) == m_mapSaveIndex[nType].end())
	{
		m_mapSaveIndex[nType][nChannelTmp] = 0;
	}


	if (!strBuffer.empty())
	{
		vector<string> vecOne;
		vector<string> vecTwo;
		vector<string> vecThrid;
		common_utils::split_string(strBuffer, vecOne, "|");//uid1-record1-tid1:tnum1,tid2:tnum2|uid2-record2-tid1:tnum1,tid2:tnum2|.... 
		for (int i = 0; i < vecOne.size(); ++i)
		{
			vecTwo.clear();
			common_utils::split_string(vecOne[i], vecTwo, "-");
			if (vecTwo.size() > 2)
			{
				RankData data;
				data.uid = base::s2i(vecTwo[0]);
				data.record_time = base::s2l(vecTwo[1]);
				this->initPlayerRandData(data);
				this->initPlayerRandData(vecTwo[2], data.items);
				m_mapRealTimeRankData[nType][nChannelTmp].push_back(data);
			}
		}
		m_mapSaveIndex[nType][nChannelTmp] += 1;
	}
}	

void ChannelRankMgr::getRankSaveString(vector<RankData> &data, vector<string> &vecOut)
{
	string strSave = "";
	int nLoop = 0;
	int nDataSize = data.size();
	for (int i = 0; i < nDataSize; ++i)
	{
		nLoop += 1;
		strSave += base::i2s(data[i].uid) + "-" + base::l2s(data[i].record_time) + "-";
		int nLoopTmp = 0;
		int nToolSize = data[i].items.size();
		for (map<int, long>::iterator iter = data[i].items.begin(); iter != data[i].items.end(); ++iter)
		{
			nLoopTmp += 1;
			strSave += base::i2s(iter->first) + ":" + base::l2s(iter->second);
			if (nLoopTmp < nToolSize) strSave += ",";
		}
		int nRem = nLoop % gSaveSizeLimit;
		if ((nLoop < nDataSize) && nRem < gSaveSizeLimit && nRem > 0) strSave += "|";
		else
		{
			vecOut.push_back(strSave);
			strSave = "";
		}
	}
}

void ChannelRankMgr::save(const int &nRankType, const int &nChannel)
{
	if (m_mapRealTimeRankData.find(nRankType) != m_mapRealTimeRankData.end())
	{
		if (m_mapRealTimeRankData[nRankType].find(nChannel) != m_mapRealTimeRankData[nRankType].end())
		{
			vector<string> vecSave;
			this->getRankSaveString(m_mapRealTimeRankData[nRankType][nChannel], vecSave);
			if (!vecSave.empty())
			{
				if (m_mapSaveIndex.find(nRankType) == m_mapSaveIndex.end())
				{
					map<int, int> mapTmp;
					m_mapSaveIndex[nRankType] = mapTmp;
				}
				if (m_mapSaveIndex[nRankType].find(nChannel) == m_mapSaveIndex[nRankType].end())
				{
					m_mapSaveIndex[nRankType][nChannel] = 0;
				}
				bool bSave = false;
				int nIndex = 0;
				QueryParam param;
				param.tableName = TBL_CHANNEL_RANK_DATA;
				param.userIdFiledName = "rank_type";
				param.userid = nRankType;
				param.keyFieldName = "channel_id";

				for (int i = 0; i < vecSave.size(); ++i)
				{
					nIndex += 1;
					bSave = m_mapSaveIndex[nRankType][nChannel] < nIndex ? true : false;
					if (m_mapSaveIndex[nRankType][nChannel] < nIndex) m_mapSaveIndex[nRankType][nChannel] = nIndex;
					param.key = nChannel * gChannelIDLimit + nIndex;

					msgpack::sbuffer sbuf;
					msgpack::packer<msgpack::sbuffer> pker(&sbuf);
					pker.pack_map(3);
					pker.pack(std::string("rank_type"));
					pker.pack(nRankType);
				    pker.pack(std::string("channel_id"));
					pker.pack(param.key);
				    pker.pack(std::string("buffer"));
					pker.pack(vecSave[i]);
					m_pDbMgr->set(param, string(sbuf.data(), sbuf.size()), bSave);
					m_pRollLog->debug("ChannelRankMgr::save result[type:%d, channel:%d, buffer:%s, index:%d, key:%d, limit:%d]", nRankType, nChannel, vecSave[i].c_str(), nIndex, param.key, gChannelIDLimit);
				}
			}
		}
	}
}


void ChannelRankMgr::sort(const int &nRankType, const int &nChannel, const bool &bSave)
{
	if (m_mapRealTimeRankData.find(nRankType) != m_mapRealTimeRankData.end())
	{
		if (m_mapRealTimeRankData[nRankType].find(nChannel) != m_mapRealTimeRankData[nRankType].end())
		{
			switch(nRankType)
			{
				case RANK_TYPE_JB: //金币榜
				{
					std::sort(m_mapRealTimeRankData[nRankType][nChannel].begin(), m_mapRealTimeRankData[nRankType][nChannel].end(), coinRankSortFunc);
					break;
				}
				case RANK_TYPE_DT: //弹头榜
				{
					std::sort(m_mapRealTimeRankData[nRankType][nChannel].begin(), m_mapRealTimeRankData[nRankType][nChannel].end(), warheadRankSortFunc);
					break;
				}	
				case RANK_TYPE_MATERIAL: //材料榜
				{
					std::sort(m_mapRealTimeRankData[nRankType][nChannel].begin(), m_mapRealTimeRankData[nRankType][nChannel].end(), meterialRankSortFunc);
					break;
				}	
				default: break;
			}
			/*
			int nRankSize = DEFAULT_RANK_SIZE;
			CsvConfig::RankType conf;
		    if(CsvConfigMgr::getInstance().findRankTypeByKey(nRankType, conf)) nRankSize = conf.get_size();
		    while(m_mapRealTimeRankData[nRankType][nChannel].size() > nRankSize) m_mapRealTimeRankData[nRankType][nChannel].pop_back();
		    */
			if (bSave) this->save(nRankType, nChannel);
		}
	}
}

string ChannelRankMgr::getPlayerChannel(const int &nUid)
{
	string strChannel = "";
	QueryParam param;
	param.tableName = TBL_PLAYER + base::i2s(nUid%10);
	param.keyFieldName = "uid";
	param.key = nUid;
	DataVector vecData;
    m_pDbMgr->get(param, vecData);
    if (vecData.size() > 0)
    {
    	msgpack::unpacked unpack;   
        msgpack::unpack(&unpack, vecData[0].data(), vecData[0].size());
        msgpack::object  obj = unpack.get();
        stringstream ss;
        ss << obj;
        m_pRollLog->debug("ChannelRankMgr::getPlayerChannel[%d:%s]", nUid, ss.str().c_str());

        Json::Reader reader;
        Json::Value value;
        if (reader.parse(ss.str(), value))
        {
			if (value.isMember("channel_id")) strChannel = value["channel_id"].asString();
        }
    }
    return strChannel;
}

int ChannelRankMgr::getPlayerChannelID(const int &nUid, string &strChannel)
{
	int nChannelId = 0;
	if (strChannel.empty())
	{
		strChannel = this->getPlayerChannel(nUid);
	}
	if (!strChannel.empty())
	{
		const std::map<int, CsvConfig::ChannelTranLimit> configMap = CsvConfigMgr::getInstance().getChannelTranLimitMap();
		for (map<int, CsvConfig::ChannelTranLimit>::const_iterator it = configMap.begin(); it != configMap.end(); ++it)
		{
			if (it->second.get_Rank() == 1)
			{
				string strChannelConf = it->second.get_Channels();
				if (!strChannelConf.empty())
				{
					strChannelConf = base::trim(strChannelConf, "\"");
					vector<string> vecSplit;
					common_utils::split_string(strChannelConf.c_str(), vecSplit, ",");
					if (find(vecSplit.begin(), vecSplit.end(), strChannel) != vecSplit.end())
					{
						nChannelId = it->first;
						break;
					}
				}
			}
		}
	}
	return nChannelId;
}


bool ChannelRankMgr::getRankList(const int &nUid, proto20rank::CProto20000Rank &data)
{
	string strChannel = "";
	int nChannelId = this->getPlayerChannelID(nUid, strChannel);
	if (nChannelId > 0)
	{
		int nType = data.m_c2s.rank_type;
		m_pRollLog->debug("ChannelRankMgr::getRankList parameter[uid:%d, type:%d, channel id:%d, channel:%s]", nUid, nType, nChannelId, strChannel.c_str());
		if (m_mapShowTimeRankData.find(nType) != m_mapShowTimeRankData.end())
		{
			if (m_mapShowTimeRankData[nType].find(nChannelId) != m_mapShowTimeRankData[nType].end())
			{
				vector<RankData>::iterator iter = m_mapShowTimeRankData[nType][nChannelId].begin();
				for (; iter != m_mapShowTimeRankData[nType][nChannelId].end(); ++iter)
				{
					proto20rank::proto_rank_data rdata;
					rdata.pid = iter ->uid;
					rdata.nick = iter->nick;
					rdata.facelook = iter->facelook;
					rdata.vip = iter->vip;
					rdata.sign = iter->sign;
					m_pRollLog->debug("ChannelRankMgr::getRankList result[uid:%d, type:%d, rank uid:%d]", nUid, nType, rdata.pid );
					switch(nType)
					{
						case RANK_TYPE_JB: //金币榜
						{
							std::map<int, long>::iterator it = iter->items.find(JB_ID);
							if(it == iter->items.end() || it->second <= 0) continue;
							else rdata.value = it->second;
							break;
						}
						case RANK_TYPE_DT: //弹头榜
						{
							for(int k = 0; k < DT_NUM; ++k)
							{
								std::map<int, long>::const_iterator it = iter->items.find(DT[k]);
								if(it == iter->items.end()) continue;
								proto20rank::proto_rank_value val;
								val.key = it->first;
								val.val = it->second;
								rdata.value2.push_back(val);
							}
							break;
						}	
						case RANK_TYPE_MATERIAL: //材料榜
						{
							for(int k = 0; k < CL_NUM; ++k)
							{
								std::map<int, long>::iterator it = iter->items.find(CL[k]);
								if(it == iter->items.end()) continue;
								proto20rank::proto_rank_value val;
								val.key = it->first;
								val.val = it->second;
								rdata.value2.push_back(val);
							}
							break;
						}	
						default: break;
					}
					data.m_s2c.list1.push_back(rdata);
				}
			}
		}
		if (nType == RANK_TYPE_JB || nType == RANK_TYPE_DT || nType == RANK_TYPE_MATERIAL) return true;
	}
	return false;
}

//上榜时间超过一个星期数据没变化则清理
void ChannelRankMgr::rankDataOverTimeCheck(const int &nRankType, const int &nChannelID)
{
	if (m_mapRealTimeRankData.find(nRankType) != m_mapRealTimeRankData.end())
	{
		if (m_mapRealTimeRankData[nRankType].find(nChannelID) != m_mapRealTimeRankData[nRankType].end())
		{
			int nNow = time(NULL);
			vector<RankData>::iterator iter = m_mapRealTimeRankData[nRankType][nChannelID].begin();
			for (; iter != m_mapRealTimeRankData[nRankType][nChannelID].end();)
			{
				if ((nNow - iter->record_time) >= SECONDS_OF_WEEK)
				{
					iter = m_mapRealTimeRankData[nRankType][nChannelID].erase(iter);
				}
				else iter++;
			}
		}
	}
}


bool ChannelRankMgr::rankDataCanInsert(const int &nRankType, map<int, long> &mapMin, map<int, long> &mapCur, bool &bSort)
{
	bool bInsert = false;
	bSort = true;
	if (nRankType == RANK_TYPE_JB) //金币榜
	{
		if (mapCur[COIN] > mapMin[COIN]) bInsert = true;	
		else bSort = false; //不满足插入条件则不需要排序
	}
	else
	{
		int nLoop = DT_NUM;
		int *pLoop = const_cast<int *>(DT);
		if (nRankType == RANK_TYPE_MATERIAL)
		{
			nLoop = CL_NUM;
			pLoop = const_cast<int *>(CL);
		} 
		for (int j = 0; j < nLoop; ++j)
		{
			m_pRollLog->debug("ChannelRankMgr::rankDataCanInsert parameter[type:%d, %d]", nRankType, *(pLoop + j));
			bSort = true;
			if (mapMin.find(*(pLoop + j)) == mapMin.end()) //最小的数据没有但当前的数据有则可以插入
			{
				if (mapCur.find(*(pLoop + j)) != mapCur.end())
				{
					bInsert = true;
					break;
				}
				else bSort = false;
			}
			else if (mapCur.find(*(pLoop + j)) == mapCur.end())//最小的数据有但当前的数据没有则不可能插入
			{
				bSort = false;
				break;
			}
			else //两者都有则比较大小
			{
				if ((mapCur[*(pLoop + j)] == mapMin[*(pLoop + j)])) bSort = false;
				else if (mapCur[*(pLoop + j)] > mapMin[*(pLoop + j)])
				{
					bInsert = true;
					break;
				}
				else
				{
					bSort = false;
					break;
				}
			}
		}
	}
	return bInsert;
}

bool ChannelRankMgr::addRankData(const int &nRankType, const int &nChannelID, RankData &data)
{
	this->rankDataOverTimeCheck(nRankType, nChannelID);
	if (m_mapRealTimeRankData.find(nRankType) == m_mapRealTimeRankData.end())
	{
		mapChannel2RankData mapTmp;
		m_mapRealTimeRankData[nRankType] = mapTmp;	
	}
	if (m_mapRealTimeRankData[nRankType].find(nChannelID) == m_mapRealTimeRankData[nRankType].end())
	{
		vector<RankData> vecTmp;
		m_mapRealTimeRankData[nRankType][nChannelID] = vecTmp;
	}
	bool bDel = true;
	for (map<int, long>::iterator iter = data.items.begin(); iter != data.items.end(); ++iter)
	{	
		if (iter->second > 0)
		{
			bDel = false;
			break;
		}
	}
	//先看已有的数据中是否有用户的数据，有则替换重新排序
	int nSize = m_mapRealTimeRankData[nRankType][nChannelID].size();
	int nRankSize = DEFAULT_RANK_SIZE;
	CsvConfig::RankType conf;
    if(CsvConfigMgr::getInstance().findRankTypeByKey(nRankType, conf)) nRankSize = conf.get_size();
    bool bRankFull = nSize == nRankSize ? true : false;
    bool bInsert = true;
    bool bSort = true;
	for (int i = 0; i < nSize; ++i)
	{
		if (m_mapRealTimeRankData[nRankType][nChannelID][i].uid == data.uid)
		{
			if (bDel) //排行榜数据为0则清除上榜
			{
				vector<RankData>::iterator iter = m_mapRealTimeRankData[nRankType][nChannelID].begin() + i;
				m_mapRealTimeRankData[nRankType][nChannelID].erase(iter);
			}
			else *(m_mapRealTimeRankData[nRankType][nChannelID].begin() + i) = data;
			bInsert = false;
			break;
		}
		if ((bRankFull) && (!bDel)) //排行榜满了则比较最后一个的数据，比最后一个数据大则可以插入排序
		{
			if (i == (nSize - 1))
			{
				bInsert = this->rankDataCanInsert(nRankType, m_mapRealTimeRankData[nRankType][nChannelID][i].items, data.items, bSort);
			}
		}
	}	
	//已有数据中没有用户的则直接插入，排序后再根据配置中的数据删除对应的数据
	if ((bInsert) && (!bDel))
	{
		if (nSize == nRankSize) m_mapRealTimeRankData[nRankType][nChannelID].pop_back();
		m_mapRealTimeRankData[nRankType][nChannelID].push_back(data);
	} 
	if (bSort) this->sort(nRankType, nChannelID);
	return true;
}


bool ChannelRankMgr::addRankData(RankData &data)
{
	bool bResult = false;
	string strChannel = data.channel;
	int nChannelID = this->getPlayerChannelID(data.uid, strChannel);
	if (nChannelID > 0)
	{
		RankData dataTmp = data;
		dataTmp.items.clear();
		//金币榜
		if (data.items.find(COIN) != data.items.end())
		{
			dataTmp.items[COIN] = data.items[COIN];
			this->addRankData(RANK_TYPE_JB, nChannelID, dataTmp);
			data.items.erase(COIN);
		}
		//弹头榜
		dataTmp.items.clear();
		for(size_t i = 0; i < DT_NUM; ++i)
		{
			if (data.items.find(DT[i]) != data.items.end())
			{
				dataTmp.items[DT[i]] = data.items[DT[i]];
				data.items.erase(DT[i]);
			}
		}
		if (!dataTmp.items.empty()) this->addRankData(RANK_TYPE_DT, nChannelID, dataTmp);
		//材料榜
		dataTmp.items.clear();
		for(size_t i = 0; i < CL_NUM; ++i)
		{
			if (data.items.find(CL[i]) != data.items.end())
			{
				dataTmp.items[CL[i]] = data.items[CL[i]];
				data.items.erase(CL[i]);
			}
		}
		if (!dataTmp.items.empty()) this->addRankData(RANK_TYPE_MATERIAL, nChannelID, dataTmp);
		if (data.items.empty()) bResult = true;
	}
	return bResult;
}


void ChannelRankMgr::fresh(time_t now)
{
	if ((now - m_nRefreshTime) >= RANK_FRESH_INTERVAL)
	{
		m_nRefreshTime = now;
		m_mapShowTimeRankData.clear();
		mapRankType2RankMapData::iterator iter = m_mapRealTimeRankData.begin();
		mapChannel2RankData::iterator it;
		for (; iter != m_mapRealTimeRankData.end(); ++iter)
		{
			if (m_mapShowTimeRankData.find(iter->first) == m_mapShowTimeRankData.end())
			{
				mapChannel2RankData mapTmp;
				m_mapShowTimeRankData[iter->first] = mapTmp;
			}
			it = iter->second.begin();
			for (; it != iter->second.end(); ++it)
			{
				if (m_mapShowTimeRankData[iter->first].find(it->first) == m_mapShowTimeRankData[iter->first].end())
				{
					vector<RankData> vecTmp(it->second);
					m_mapShowTimeRankData[iter->first][it->first] = vecTmp;
				}
			}
		}
	}
}
